package com.invest.infra.excel.export;

import com.invest.infra.template.TemplateUtils;
import org.apache.commons.collections.CollectionUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;


public abstract class ExcelProvider<T> {
	
	private static final int FLUSH_NUMBER;

	public abstract List<T> getDataSource();
	
	public abstract String getExcelName();

	public abstract String getTemplatePath();
	
	public abstract String getTemplateHeaderName();
	
	public abstract String getTemplateContentName();
	
	public abstract String getTemplateFooterName();
	
	static{
		//output flush number
		FLUSH_NUMBER  = 200;
	}

	private String getTemplateText(String templateName,T t){
		String content = null;
		if(null != templateName ){
			content =  TemplateUtils.getFileTmpContent(getTemplatePath()+templateName, t);
		}
		return content == null ? "" : content;
	}
	
	private String getTemplateContentText(T t){
		
		String templateName = getTemplateContentName();
		return getTemplateText(templateName,t);
	}
	
	private String getTemplateHeaderText(){
		
		String templateName = getTemplateHeaderName();
		return getTemplateText(templateName,null);
	}
	
	private String getTemplateFooterText(){
		String templateName = getTemplateFooterName();
		return getTemplateText(templateName,null);
	}
	
	
	public void writeTemplateHeader(OutputStream os){
		String str = getTemplateHeaderText();
		if(null != str){
			try {
				os.write(str.getBytes());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	public void writeTemplateFooter(OutputStream os){
		
		String str = getTemplateFooterText();
		if(null != str){
			try {
				os.write(str.getBytes());
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
	
	public void writeContent(OutputStream os){
		
		List<T> list = getDataSource();
		int i =1;
		if(CollectionUtils.isNotEmpty(list)){
			try {
				for(T t : list){
					
					String str = getTemplateContentText(t);
					os.write(str.getBytes());
					
					if(i % FLUSH_NUMBER == 0){
						os.flush();
					}
				}
				os.flush();
			}catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}
}
